<template>
  <div>
    <div v-if="type === 'card'"
         class="upload-card-components"
         :class="`${size} ${limit === 1 ? 'is-single' : ''}`">
      <el-upload :action="uploadUrl"
                 :headers="headers"
                 list-type="picture-card"
                 :on-preview="onPreview"
                 :on-success="onSuccess"
                 :file-list="fileList"
                 :on-remove="onRemove"
                 :limit="limit"
                 :multiple="multiple"
                 :before-upload="beforeUpload">
        <i class="el-icon-plus"></i>
        <div class="el-upload__tip"
             slot="tip"
             style="width: 360px;white-space: pre-wrap;line-height: 18px;">
          {{ tip === '' ? `最多可上传${limit}个文件` : tip }}
        </div>
      </el-upload>
    </div>
    <div v-if="type === 'btn'">
      <el-button type="primary"
                 @click="updateVisible = true">{{
        fileList.length === 0 ? btnText : "重新上传"
      }}</el-button>
      <el-dialog class="main-dialog"
                 title="选择文件"
                 :visible.sync="updateVisible"
                 :append-to-body="true"
                 :modal-append-to-body="true"
                 width="400px">
        <div class="upload-btn-components">
          <el-upload :action="uploadUrl"
                     :headers="headers"
                     drag
                     :on-preview="onPreview"
                     :on-success="onSuccess"
                     :file-list="fileList"
                     :on-remove="onRemove"
                     :limit="limit"
                     :multiple="multiple"
                     :before-upload="beforeUpload">
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">
              将文件拖到此处，或<em>点击上传</em>
            </div>
            <div class="el-upload__tip"
                 slot="tip"
                 style="width: 360px">
              {{ tip === "" ? `最多可上传${limit}个文件` : tip }}
            </div>
          </el-upload>
        </div>
        <span slot="footer"
              class="dialog-footer">
          <el-button type="primary"
                     @click="updateVisible = false">确 定</el-button>
        </span>
      </el-dialog>
    </div>
    <el-upload v-if="type === 'btn-file'"
               :action="uploadUrl"
               :headers="headers"
               :on-preview="onPreview"
               :on-success="onSuccess"
               :file-list="fileList"
               :on-remove="onRemove"
               :limit="limit"
               :multiple="multiple"
               :before-upload="beforeUpload">
      <el-button type="primary">{{
        fileList.length === 0 ? btnText : "重新上传"
      }}</el-button>
      <div slot="tip"
           class="el-upload__tip"
           style="width: 360px">
        {{ tip === "" ? `最多可上传${limit}个文件` : tip }}
      </div>
    </el-upload>
    <ElImageViewer v-if="showViewer"
                   :on-close="
        () => {
          this.showViewer = false;
        }
      "
                   :url-list="[imgViewerPath]" />
  </div>
</template>
<script>
import ElImageViewer from "element-ui/packages/image/src/image-viewer";
import { deepCopy } from "@/utils/deepCopy";
export default {
  // 单张图片上传时 绑定的是单个图片Object 多张图片上传时 绑定多张图片Object的数组
  // {
  //   name: 'xxx',
  //   type: 'png',
  //   size: '10000',
  //   url: 'xxxxx'
  // }
  model: {
    prop: "modelVal",
    event: "change",
  },
  props: {
    modelVal: {
      type: [Object, Array, String],
      default: null
    },
    // 图片上传路径
    uploadUrl: {
      type: String,
      default:
        process.env.VUE_APP_BASE_URL +
        "/logFile/upload",
    },
    // 图片上传请求头
    headers: {
      type: Object,
      default: function () {
        return {
          "authToken": localStorage.getItem("token"),
        };
      },
    },
    // 最大上传个数
    limit: {
      type: Number,
      default: 1,
    },
    // medium
    size: {
      type: String,
      default: "small",
    },
    // card: 卡片上传 btn: 按钮弹窗上传 btn-file: 按钮不带弹窗上传
    type: {
      type: String,
      default: "card",
    },
    // 按钮上传的文案
    btnText: {
      type: String,
      default: "上传文件",
    },
    // 上传提示
    tip: {
      type: String,
      default: "",
    },
    // 是否支持多选文件
    multiple: {
      type: Boolean,
      default: false,
    },
    // 允许的上传格式
    format: {
      type: Array,
      default: () => [],
    },
    // 文件大小的限制
    fileSize: {
      type: Number,
      default: 1024 * 10 * 10,
    },
    ispixel: {
      type: Boolean,
      default: false
    },
    fileWidth: {
      type: Number,
      default: 0
    },
    fileHeight: {
      type: Number,
      default: 0
    },
    // 是否上传视频
    videos: {
      type: Boolean,
      default: false,
    },
  },
  components: {
    ElImageViewer,
  },
  data () {
    return {
      showViewer: false,
      imgViewerPath: "",
      fileList: [],
      updateVisible: false,
    };
  },
  watch: {
    modelVal: {
      handler: function (val) {
        if (!val) {
          this.fileList = [];
        } else {
          if (this.limit === 1) {
            this.fileList = [val];
          } else {
            // console.log(val)
            this.fileList = deepCopy(val.map(item => {
              return {
                ...item,
                url: process.env.VUE_APP_BASE_URL + process.env.VUE_APP_FILE_URL + item.url
              }
            }))
          }
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    // 查看图片
    onPreview (file) {
      this.showViewer = true;
      this.imgViewerPath = file.url;
    },

    // 上传文件格式大小拦截
    beforeUpload (file, fileWidth = this.fileWidth, fileHeight = this.fileHeight) {
      if (this.format.length === 0) return true;
      // 判断图片格式
      const fileFormat = file.name.substring(file.name.lastIndexOf(".") + 1);
      const formatState = this.format.indexOf(fileFormat) > -1;
      if (!formatState) {
        this.$message({
          message: `只允许上传${this.format.join()}格式的文件，请重新选择！`,
          type: "warning",
        });
      }
      // 判断图片大小
      const fileSizeState = file.size / 1024 / 1024 < this.fileSize;
      if (!fileSizeState) {
        this.$message({
          message: "上传文件过大，请重新选择!",
          type: "warning",
        });
      }
      // 判断图片尺寸
      const _this = this
      const isSize = new Promise(function (resolve, reject) {
        let width = fileWidth;
        let height = fileHeight;
        let _URL = window.URL || window.webkitURL;
        let img = new Image();
        if (_this.ispixel) {
          img.onload = function () {
            let valid = img.width == width && img.height == height;
            valid ? resolve() : reject();
          }
        } else {
          resolve()
        }
        img.src = _URL.createObjectURL(file);
      }).then(() => {
        return file;
      }, (errs) => {
        console.log(errs)
        this.$message.error(`图片尺寸必须是${fileWidth}*${fileHeight}!`);
        return Promise.reject();
      });
      return formatState && fileSizeState && isSize;
    },

    // 上传成功回调
    onSuccess (_, __, fileList) {
      const copyFileList = deepCopy(fileList).map(item => {
        if (item.response) {
          return item
        } else {
          return {
            ...item,
            url: item.data || item.name
          }
        }
      })
      console.log(copyFileList)
      // console.log(fileList)
      this.update(copyFileList);
    },

    // 删除文件回调
    onRemove (_, fileList) {
      const copyFileList = deepCopy(fileList).map(item => {
        if (item.response) {
          return item
        } else {
          return {
            ...item,
            url: item.data || item.name
          }
        }
      })
      this.update(copyFileList);
    },

    // 数据处理
    update (val) {
      if (this.limit === 1) {
        const dataObj = val[0] || null;
        const result = dataObj
        console.log(dataObj)
          ? {
            name: dataObj.name,
            type: dataObj.raw ? dataObj.raw.type : "",
            size: dataObj.size,
            baseUrl: '',
            url: dataObj.response
              ? '' + dataObj.response.data.url
              : "",
            date: dataObj.raw ? dataObj.raw.lastModified : "",
            data: dataObj.response.data.url || "",
          }
          : null;
        this.$emit("update:modelValue", result);
        this.$emit("change", result);
      } else {
        const resultList = val.map((file) => {
          if (file.response) {
            return {
              name: file.name,
              type: file.raw ? file.raw.type : "",
              size: file.size,
              baseUrl: '',
              url: file.response
                ? '' + file.response.data.uploadPath
                : "",
              date: file.raw ? file.raw.lastModified : "",
              data: file.response.data.uploadPath || "",
            };
          } else {
            return file;
          }
        });
        console.log(resultList);
        this.$emit("update:modelValue", resultList);
        this.$emit("change", resultList);
      }
    },
  },
};
</script>

<style lang="scss" scoped="scoped">
/deep/ .upload-card-components {
  width: auto !important;
  min-height: 200px !important;
  .el-upload--picture-card {
  }
}

.upload-btn-components {
  margin: 20px auto;
  display: flex;
  justify-content: center;
  .el-upload-list {
    .el-upload-list__item-name {
      width: 300px;
    }
  }
}

// 默认
.small {
  .el-upload--picture-card {
    width: 82px;
    height: 82px;
    line-height: 92px;
  }
  .el-upload-list__item {
    width: 82px;
    height: 82px;
  }
}

// 大号
.medium {
  .el-upload--picture-card {
    width: 132px;
    height: 132px;
    line-height: 142px;
    .el-upload-list__item {
      width: 132px;
      height: 132px;
    }
  }
}

// 单个上传
.is-single {
  overflow: hidden;
  width: 82px;
  height: 82px;
}
</style>
